package com.bc.bcapi.utils.web3j;

import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.core.methods.response.Transaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class ERC20TransactionModel {

    private String txhash;
    private Transaction transaction;
    private TransactionReceipt transactionReceipt;
    private Boolean status;
    private List<TransModel> transModels = new ArrayList<>();
    private BigInteger gasUsed;
    private BigDecimal gasCost;

    public void setTransaction(Transaction transaction) {
        this.transaction = transaction;
    }

    public ERC20TransactionModel(Transaction transaction, TransactionReceipt transactionReceipt) {
        setTransaction(transaction);
        setTransactionReceipt(transactionReceipt);
        explode();
    }

    private void explode() {
        setTxhash(getTransaction().getHash());
        setGasUsed(getTransactionReceipt().getGasUsed());
        BigInteger gasCostInt = getTransaction().getGasPrice().multiply(getTransactionReceipt().getGasUsed());
        setGasCost(Util.Wei2ETH(gasCostInt));
        setStatus(false);
        if (getTransactionReceipt().getStatus().equals("0x1")) {
            setStatus(true);
        }

        String orgin_to = getTransaction().getTo();
        if (orgin_to != null) {
            List<Log> logs = getTransactionReceipt().getLogs();
            if (logs.size() == 0) {
                //按照ETH处理
                if (getTransactionReceipt().getStatus().equals("0x1")) {
                    TransModel transModel = new TransModel();
                    transModel.setFrom(Util.inAddressFormat(getTransactionReceipt().getFrom()));
                    transModel.setTo(Util.inAddressFormat(getTransactionReceipt().getTo()));
                    transModel.setValue(getTransaction().getValue());
                    transModel.setContract_address(Util.getETHADDRESS());
                    addTransModel(transModel);
                }
            } else {
                //按照ERC20处理
                for (Log log: logs) {
                    List<String> topics = log.getTopics();
                    if (topics.size() == 3) {
                         if (topics.get(0).equals(Util.getTRANSFERMETHOD())) {
                             //有效的transfer
                             String from = topics.get(1);
                             String to = topics.get(2);
                             TransModel transModel = new TransModel();
                             transModel.setContract_address(log.getAddress());
                             transModel.setFrom(Util.topic2address(from));
                             transModel.setTo(Util.topic2address(to));
                             transModel.setValue(Util.hex2BigInt(log.getData()));
                             addTransModel(transModel);
                         }
                    }
                }
            }
        }
    }

    public String getTxhash() {
        return txhash;
    }

    public void setTxhash(String txhash) {
        this.txhash = txhash;
    }

    public TransactionReceipt getTransactionReceipt() {
        return transactionReceipt;
    }

    public void setTransactionReceipt(TransactionReceipt transactionReceipt) {
        this.transactionReceipt = transactionReceipt;
    }

    public Transaction getTransaction() {
        return transaction;
    }

    public List<TransModel> getTransModels() {
        return transModels;
    }

    public void addTransModel(TransModel transModel) {
        this.transModels.add(transModel);
    }

    public BigInteger getGasUsed() {
        return gasUsed;
    }

    public void setGasUsed(BigInteger gasUsed) {
        this.gasUsed = gasUsed;
    }

    public BigDecimal getGasCost() {
        return gasCost;
    }

    public void setGasCost(BigDecimal gasCost) {
        this.gasCost = gasCost;
    }

    public Boolean getStatus() {
        return status;
    }

    public void setStatus(Boolean status) {
        this.status = status;
    }

}
